package com.mgface.jersey.resources;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.mgface.jersey.entity.User;
import com.mgface.jersey.service.UserService;


/**
 * 如果是原型的模式,你可以将这些@Context等annotation用在变量、set方法或者是构造方法上。</p>
 * 如果是单例模式,则不允许,因为对象会同时处理多个请求,如果将这些值用在变量或者set方法上,则多个请求会彼此冲突,陷入错误。
 * @author yuxiang
 *
 */
@Path("/first")
@Component
@Singleton
public class FirstResource {

	@Autowired
	private UserService userService;

	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayHello(@DefaultValue("1") @QueryParam("keyword") String keyword) {
		System.out.println("keyword:" + keyword);
		return "hello";
	}

	@POST
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	public User postAdd(@FormParam("id") String userId) throws Exception {
		System.out.println("userId:"+userId);
		Objects.requireNonNull(userService);
		return userService.getUserInfo(userId);
	}
	
	/*@POST
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Consumes(MediaType.APPLICATION_JSON)
	public User postAdd(User user) throws Exception {
		Objects.requireNonNull(userService);
		user.setCreateTime(new Date());
		return user;
	}*/
	
	@POST
	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
	@Consumes(MediaType.APPLICATION_JSON)
	public User postAsynAdd(User user) throws Exception {
		Objects.requireNonNull(userService);
		user.setCreateTime(new Date());
		//Thread.sleep(5000); //做异步测试的时候启用之后看效果很明显
		return user;
	}
	
	@PUT 
    public Response putUser(User user) {  
       System.out.println(user.getUserId()); 
       return Response.status(Status.NO_CONTENT).build();
    } 
	
	@DELETE
	@Path("delete/{id}")
	public Response delete(@PathParam("id") String id){
		System.out.println("delete id="+id);
		return Response.ok("delete").build();
	}
	
	@GET
	@Path("all")
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getAll() {
        List<User> users = new ArrayList<>();
        try {
			users.add(userService.getUserInfo("1001"));
		} catch (Exception e) {
			e.printStackTrace();
		}
        return users;
//        //像这些集合的话也可以转成json处理,就不需要这样麻烦,不可定制
//        GenericEntity<List<User>> UserWrapper = new GenericEntity<List<User>>(users) {};
//        return Response.ok(UserWrapper).build();
    }
	
	@GET
	@Path("etag")
	@Produces({MediaType.TEXT_PLAIN})
	public Response testEtag(@Context Request request){
		EntityTag tag = new EntityTag(String.valueOf("123457".hashCode()), true);
		CacheControl cc = new CacheControl();
		cc.setMaxAge(50);
		ResponseBuilder builder = request.evaluatePreconditions(tag);
		System.out.println("builder="+builder);
		if(builder!=null){
			builder.cacheControl(cc);
			return builder.build();
		}
		ResponseBuilder rb = Response.ok(String.valueOf("12345".hashCode()));
		rb.cacheControl(cc);
		rb.tag(tag);
		return rb.build();
	}
	
	
	@SuppressWarnings("deprecation")
	@GET
	@Path("book")
	@Produces({MediaType.TEXT_PLAIN})
	public Response getBook(){
		ResponseBuilder rb = Response.ok("book");
		CacheControl cc = new CacheControl();
		cc.setMaxAge(10);//max-age用于指示缓存的有效期；如果max-age和Expires同时指定，则max-age有效
		cc.setNoCache(false);//true:所有内容都不会被缓存
		//cc.setNoStore(false);//true:所有内容都不会被缓存到缓存或 Internet临时文件中
		cc.setNoTransform(true);//有时缓存会被自动进行转换以节省内存或者带宽,例如压缩图像.no-transform用于指定不允许进行数据转换
		cc.setPrivate(false);//false所有内容都将被缓存 true:内容只缓存到私有缓存中
		cc.setMustRevalidate(true);//如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证
		rb.expires(new Date(2015, 12, 29));//对象来设置有效期
		rb.cacheControl(cc);
		return rb.language(Locale.CHINA).header("author", "mgface").build();
	}
	
	@GET
	@Path("void")
	@Produces({MediaType.TEXT_PLAIN})
	public void testReturnNull(){
		//Response.status(Status.NO_CONTENT).build();
		throw new WebApplicationException(Status.NOT_FOUND);
	}

	@Path("{id}")
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response getAdd(@DefaultValue("1") @QueryParam("id") String id, @Context HttpServletResponse response,
			@Context HttpServletRequest request) throws Exception {
		HttpSession session = request.getSession();
		session.setAttribute("result", id);
		Cookie cookie = new Cookie("author", "mgface");
		NewCookie newCookie = new NewCookie(cookie, "mgface", 10*60, null, true, true);
		Map<String, String> map = new HashMap<>();
		map.put("key", "456");
		map.put("result", id);
		return Response.status(Status.OK).entity(map).cookie(newCookie).build();
		// return Response.status(Status.FOUND).entity(map).header("Location",
		// "http://www.baidu.com").build();
		// request.getRequestDispatcher("/WEB-INF/page/result.jsp").forward(request,
		// response);
	}
}
